package com.kgdev.cweb.mbean.store.order;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import com.kgdev.cweb.beans.prod.impl.ClientBean;
import com.kgdev.cweb.beans.prod.impl.OrderBean;
import com.kgdev.cweb.beans.prod.impl.OrderDraftBean;
import com.kgdev.cweb.beans.pub.impl.ChocolateColorBean;
import com.kgdev.cweb.beans.pub.impl.ChocolateColorBodyBean;
import com.kgdev.cweb.beans.pub.impl.ChocolateTypeBean;
import com.kgdev.cweb.beans.pub.impl.PlateArticleBean;
import com.kgdev.cweb.beans.pub.impl.PlatePackingBean;
import com.kgdev.cweb.beans.pub.impl.ShippingTypeBean;
import com.kgdev.cweb.entities.prod.managed.Client;
import com.kgdev.cweb.entities.prod.managed.Order;
import com.kgdev.cweb.entities.prod.managed.OrderDraft;
import com.kgdev.cweb.entities.prod.owned.client.ClientShippingInfo;
import com.kgdev.cweb.entities.prod.owned.order.OrderAdminParam;
import com.kgdev.cweb.entities.prod.owned.order.OrderAttributes;
import com.kgdev.cweb.entities.prod.owned.order.OrderPattern;
import com.kgdev.cweb.entities.pub.ChocolateColor;
import com.kgdev.cweb.entities.pub.ChocolateColorBody;
import com.kgdev.cweb.entities.pub.ChocolateType;
import com.kgdev.cweb.entities.pub.OrderStatus;
import com.kgdev.cweb.entities.pub.PlateArticle;
import com.kgdev.cweb.entities.pub.PlatePacking;
import com.kgdev.cweb.entities.pub.ShipingType;
import com.kgdev.cweb.entities.sys.Image;
import com.kgdev.cweb.mbean.global.session.LoginBean;

@ManagedBean
@SessionScoped
public class CopyOfOrderAdd implements Serializable {

	@EJB
	OrderBean orderBean;
	@EJB
	OrderDraftBean orderDraftBean;
	@EJB
	PlateArticleBean plateArticleBean;
	@EJB
	ChocolateTypeBean chocolateTypeBean;
	@EJB
	ChocolateColorBean chocolateColorBean;
	@EJB
	ChocolateColorBodyBean chocolateColorBodyBean;
	@EJB
	PlatePackingBean platePackingBean;
	@EJB
	ClientBean clientBean;
	@EJB
	ShippingTypeBean shippingTypeBean;

	@ManagedProperty(value = "#{loginBean}")
	LoginBean loginBean;

	private List<Integer> quantities;

	private List<ChocolateType> chocolateTypes;

	private List<PlatePacking> platePackings;

	private List<PlateArticle> plateArticles;

	private List<ChocolateColor> chocolateColors;

	private List<ChocolateColorBody> chocolateBodyColors;

	private Order order;

	private OrderDraft orderDraft;

	private Integer chocolateTypeId;
	private Integer platePackingId;
	private String bodyColorId;
	private String inscriptionColorId;
	private String logoColorId;
	private String plateArticleId;
	private String plateColorId;
	private Integer shippingTypeId;
	private Integer clientShippingInfoId;

	private static final long serialVersionUID = 1L;

	public String addOrder() {
		convertDraftToOrder();
		orderBean.add(order);
		orderDraftBean.remove(orderDraft.getOrderDraftId());
		orderDraft = null;
		order = null;
		return "toStoreOrderList";
	}

	public String getBodyColorId() {
		return bodyColorId;
	}

	public StreamedContent getBufferDownloadFile() {
		InputStream stream = new ByteArrayInputStream(orderDraft.getLogotype()
				.getContent());
		return new DefaultStreamedContent(stream, orderDraft.getLogotype()
				.getContentType(), orderDraft.getOrderName());
	}

	public List<ChocolateColorBody> getChocolateBodyColors() {
		return chocolateBodyColors;
	}

	public List<ChocolateColor> getChocolateColors() {
		return chocolateColors;
	}

	public Integer getChocolateTypeId() {
		return chocolateTypeId;
	}

	public List<ChocolateType> getChocolateTypes() {
		return chocolateTypes;
	}

	public Integer getClientShippingInfoId() {
		return clientShippingInfoId;
	}

	public String getInscriptionColorId() {
		return inscriptionColorId;
	}

	public int getInscriptionCountDown() {
		if (orderDraft.getInscription() == null) {
			return 45;
		}
		return 45 - orderDraft.getInscription(). // TODO hardcoded 45
				toCharArray().length;
	}

	public String getLogoColorId() {
		return logoColorId;
	}

	public Order getOrder() {
		return order;
	}

	public OrderDraft getOrderDraft() {
		return orderDraft;
	}

	public String getPlateArticleId() {
		return plateArticleId;
	}

	public List<PlateArticle> getPlateArticles() {
		return plateArticles;
	}

	public String getPlateColorId() {
		return plateColorId;
	}

	public Integer getPlatePackingId() {
		return platePackingId;
	}

	public List<PlatePacking> getPlatePackings() {
		return platePackings;
	}

	public List<Integer> getQuantities() {
		return quantities;
	}

	public Integer getShippingTypeId() {
		return shippingTypeId;
	}

	public void handleLogotypeUpload(FileUploadEvent event) {
		UploadedFile file = event.getFile();
		System.err.println("File name: " + file.getFileName());

		try {
			orderDraft.setOrderName(new String(file.getFileName().getBytes(),
					"utf8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace(); // TODO
		}

		byte[] content = file.getContents(); // TODO stub

		Image logotype = new Image();
		logotype.setContent(content);
		logotype.setFileName(file.getFileName());
		logotype.setContentType(file.getContentType());

		orderDraft.setLogotype(logotype);

		String message = "Upload sucessful";
		FacesMessage facesMessage = new FacesMessage(message,
				file.getFileName());
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);

	}

	@PostConstruct
	public void init() {
		initQuantities();
		initLists();
		initEmptyOrderDraft();
	}

	public void initLists() {
		chocolateTypes = chocolateTypeBean.findAll();
		chocolateBodyColors = chocolateColorBodyBean.findAll();
		chocolateColors = chocolateColorBean.findAll();
		plateArticles = plateArticleBean.findAll();
		platePackings = platePackingBean.findAll();
	}

	public boolean logotypeExists() {
		return orderDraft.getLogotype() != null;
	}

	public String makeOrderFromDraft(Integer orderDraftId) {

		System.err.println("orderdraftId = " + orderDraftId);
		orderDraft = orderDraftBean.find(orderDraftId);
		System.err.println("orderdraft = " + orderDraft);

		fillIds();

		return "makeOrderFromDraft";
	}

	public String previewOrder() {
		saveDraft();
		return "toOrderAddPreview";
	}

	public void resetLogotype() {
		orderDraft.setLogotype(null);

	}

	public String saveDraft() {
		processOrderDraft();

		System.err.println("entering edit: PlateArticleId internal:"
				+ plateArticleId);
		if (orderDraftBean.find(orderDraft.getOrderDraftId()) == null)
			orderDraftBean.add(orderDraft);
		else {
			orderDraftBean.edit(orderDraft);
		}
		return "saveDraft";
	}

	public void setBodyColorId(String bodyColorId) {
		this.bodyColorId = bodyColorId;
	}

	public void setChocolateBodyColors(
			List<ChocolateColorBody> chocolateBodyColors) {
		this.chocolateBodyColors = chocolateBodyColors;
	}

	public void setChocolateColors(List<ChocolateColor> chocolateColors) {
		this.chocolateColors = chocolateColors;
	}

	public void setChocolateTypeId(Integer chocolateTypeId) {
		this.chocolateTypeId = chocolateTypeId;
	}

	public void setChocolateTypes(List<ChocolateType> chocolateTypes) {
		this.chocolateTypes = chocolateTypes;
	}

	public void setClientShippingInfoId(Integer clientShippingInfoId) {
		this.clientShippingInfoId = clientShippingInfoId;
	}

	public void setInscriptionColorId(String inscriptionColorId) {
		this.inscriptionColorId = inscriptionColorId;
	}

	public void setLoginBean(LoginBean loginBean) {
		this.loginBean = loginBean;
	}

	public void setLogoColorId(String logoColorId) {
		this.logoColorId = logoColorId;
	}

	public void setOrder(Order order) {
		this.order = order;
	}

	public void setOrderDraft(OrderDraft orderDraft) {
		this.orderDraft = orderDraft;
	}

	public void setPlateArticleId(String plateArticleId) {
		this.plateArticleId = plateArticleId;
	}

	public void setPlateArticles(List<PlateArticle> plateArticles) {
		this.plateArticles = plateArticles;
	}

	public void setPlateColorId(String plateColorId) {
		this.plateColorId = plateColorId;
	}

	public void setPlatePackingId(Integer platePackingId) {
		this.platePackingId = platePackingId;
	}

	public void setPlatePackings(List<PlatePacking> platePackings) {
		this.platePackings = platePackings;
	}

	public void setQuantities(List<Integer> quantities) {
		this.quantities = quantities;
	}

	public void setShippingTypeId(Integer shippingTypeId) {
		this.shippingTypeId = shippingTypeId;
	}

	private void convertDraftToOrder() {
		order = new Order();
		order.setClient(orderDraft.getClient());
		order.setOrderDate(new Date(Calendar.getInstance().getTimeInMillis()));
		order.setOrderName(orderDraft.getOrderName());
		order.setOrderAttributes(processOrderAttributes(orderDraft));
		order.setOrderPattern(processOrderPattern(orderDraft));
		order.setStatus(new OrderStatus("New"));
		order.setOrderAdminParam(new OrderAdminParam());
	}

	private void fillIds() {

		ChocolateType chocolateType = orderDraft.getChocolateType();
		PlatePacking platePacking = orderDraft.getPlatePacking();
		ChocolateColorBody bodyColor = orderDraft.getBodyColor();
		ChocolateColor inscriptionColor = orderDraft.getInscriptionColor();
		ChocolateColor logoColor = orderDraft.getLogoColor();
		PlateArticle plateArticle = orderDraft.getPlateArticle();
		ChocolateColor plateColor = orderDraft.getPlateColor();
		ShipingType shippingType = orderDraft.getShippingType();
		ClientShippingInfo clientShippingInfo = orderDraft
				.getClientShippingInfo();

		if (bodyColor != null)
			bodyColorId = bodyColor.getChocolateColor();
		else
			bodyColorId = null;

		if (chocolateType != null)
			chocolateTypeId = chocolateType.getChocolateId();
		else
			chocolateTypeId = null;

		if (clientShippingInfo != null)
			clientShippingInfoId = clientShippingInfo.getShippingId();
		else
			clientShippingInfoId = null;

		if (inscriptionColor != null)
			inscriptionColorId = inscriptionColor.getChocolateColor();
		else
			inscriptionColorId = null;

		if (logoColor != null)
			logoColorId = logoColor.getChocolateColor();
		else
			logoColorId = null;

		if (plateArticle != null)
			plateArticleId = plateArticle.getArticleId();
		else
			plateArticleId = null;

		if (plateColor != null)
			plateColorId = plateColor.getChocolateColor();
		else
			plateColorId = null;

		if (platePacking != null)
			platePackingId = platePacking.getPackingId();
		else
			platePackingId = null;

		if (shippingType != null)
			shippingTypeId = shippingType.getShiptypeId();
		else
			shippingTypeId = null;

	}

	private void initEmptyOrderDraft() {
		orderDraft = new OrderDraft();
		Client client = loginBean.getAutenticatedClient();
		orderDraft.setClient(client);
		orderDraft.setPlateArticle(new PlateArticle());
		orderDraft.setOrderDraftDate(new Date(Calendar.getInstance().getTime().getTime()));
	}

	private void initQuantities() {

		// TODO stub
		quantities = new ArrayList<>();
		quantities.add(100);
		quantities.add(200);
		quantities.add(500);
		quantities.add(1000);
		quantities.add(2000);
		quantities.add(5000);
		quantities.add(10000);
		quantities.add(20000);
		quantities.add(50000);
	}

	private OrderAttributes processOrderAttributes(OrderDraft orderDraft) {
		OrderAttributes orderAttributes = new OrderAttributes();
		orderAttributes.setBodyColor(orderDraft.getBodyColor());
		orderAttributes.setLogoColor(orderDraft.getLogoColor());
		orderAttributes.setInscriptionColor(orderDraft.getInscriptionColor());
		orderAttributes.setPlateColor(orderDraft.getPlateColor());
		orderAttributes.setQuantity(orderDraft.getQuantity());
		return orderAttributes;

	}

	private void processOrderDraft() {

		ChocolateType chocolateType = chocolateTypeBean.find(chocolateTypeId);
		PlatePacking platePacking = platePackingBean.find(platePackingId);
		ChocolateColorBody bodyColor = chocolateColorBodyBean.find(bodyColorId);
		ChocolateColor inscriptionColor = chocolateColorBean
				.find(inscriptionColorId);
		ChocolateColor logoColor = chocolateColorBean.find(logoColorId);
		PlateArticle plateArticle = plateArticleBean.find(plateArticleId);
		ChocolateColor plateColor = chocolateColorBean.find(plateColorId);
		ShipingType shippingType = shippingTypeBean.find(shippingTypeId);

		// lookup for client shipping info
		ClientShippingInfo clientShippingInfo = new ClientShippingInfo();
		clientShippingInfo.setShippingId(clientShippingInfoId);
		Integer index = orderDraft.getClient().getClientShippingInfos()
				.indexOf(clientShippingInfo);
		if (index == -1) {
			clientShippingInfo = null;
		} else {
			clientShippingInfo = orderDraft.getClient()
					.getClientShippingInfos().get(index);
		}
		// lookup for client shipping info

		orderDraft.setChocolateType(chocolateType);
		orderDraft.setPlatePacking(platePacking);

		orderDraft.setBodyColor(bodyColor);
		orderDraft.setInscriptionColor(inscriptionColor);
		orderDraft.setLogoColor(logoColor);
		orderDraft.setPlateArticle(plateArticle);
		orderDraft.setPlateColor(plateColor);
		orderDraft.setShippingType(shippingType);
		orderDraft.setClientShippingInfo(clientShippingInfo);
	}

	private OrderPattern processOrderPattern(OrderDraft orderDraft) {
		OrderPattern orderPattern = new OrderPattern();
		orderPattern.setLogotype(orderDraft.getLogotype());
		orderPattern.setInscription(orderDraft.getInscription());
		orderPattern.setHasFrame(orderDraft.getHasFrame());
		return orderPattern;
	}
}
